Skip to content

feat(forge): carry the owner-qualified actor handle on the wire (RIG-3326) - #1020

Open
rigel-mintaka wants to merge 1 commit into
compass-forge/rig-3331-toolsfrom
compass-forge/rig-3326-owner-wire
Open

feat(forge): carry the owner-qualified actor handle on the wire (RIG-3326)#1020
rigel-mintaka wants to merge 1 commit into
compass-forge/rig-3331-toolsfrom
compass-forge/rig-3326-owner-wire

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

This PR is part of a stack containing 6 PRs:

  1. main
  2. feat(forge): forge state-transition wire arms and provider methods (RIG-3331) #1017
  3. feat(server): forge state-transition arms and actor memo (RIG-3331) #1018
  4. feat(agent): forge state-transition tools (RIG-3331) #1019
  5. "feat(forge): carry the owner-qualified actor handle on the wire (RIG-3326)" (this PR)
  6. feat(tools): mint the live-oracle Linear token with app:assignable (RIG-3299) #1021
  7. refactor(proto): standardize the PR-number wire field on pr_number (RIG-3561) #1037

Implements T0 of the RIG-3326 record (docs/designs/server/compass-forge-self-delegate-suppression/design.md, under review in #997). Stacked on #1019.

Restores the owner on attribution so the notify router has an owner-qualified actor at all. Without this the whole COMMENT/REVIEW suppression arm is structurally inert.

  • AgentAttribution regains owner_handle = 2. Field 2 is legitimately reclaimable per DL-186: no wire build ever shipped the earlier owner/verified shape and nothing on disk is proto-encoded, so the number carries no compatibility obligation.
  • Populated at the three sites that already parse the owner and currently discard it — stripBodyToRef, linearCommentRef, detectArtifact — each from author.OwnerHandle. No new parse, no new store read: the value is in hand at every one of them.

The UI adapter is a live consumer, not dead code

adaptAgentAttribution in apps/ui/src/live/adapt.ts hardcoded ownerHandle: "" and its doc comment justified that by citing DL-094's "no wire source" reservation. After this change there IS a wire source, so leaving it would silently discard a real value behind a stale citation. The domain type already carried the field and two tests pinned the empty default.

Threaded through, comment re-pointed at DL-339, both assertions updated. verified stays hedged — DL-094's attribution-is-not-a-trust-claim core is unchanged, and DL-339 amends only the owner clause.

Note on the carrier

ForgeEvent gains no actor field. Matt ruled OQ-1 on 2026-09-07: the STATE actor is resolved from RIG-3331's forge_state_transitions memo at the actor-resolution seam, keyed on the event's coordinate + applied state. An Actor field would have shipped with no populator and no consumer (rule://no-inert-gating). A memo miss resolves no actor, so STATE fails open until the op is writing memos.

Tests

The three parse sites round-trip both handles; a header carrying no owner yields an empty OwnerHandle — asserted explicitly, because that is the fail-open input the suppression predicate relies on. The two UI assertions carry the owner through. The Go attribution-render callers are unaffected and verified still building.

Ledger-impact: none — DL-338/DL-339 land with the record itself in #997, not here.

Review round 1 — resolved

Reviewed by the review agent over the whole stack (high 3, medium 7, low 6).
The core RIG-3331 mechanism (memo ordering, one-shot consume, tenant isolation,
provider methods, Linear resolution, error mapping, recorded-state choice) was
verified correct. All three highs were stack-integration regressions, now fixed:

  • Stale base / three generated-file conflicts — rebased the line onto current
    main; every conflict resolved by regenerating (buf + sqlc), never by
    hand-merging a generated file.
  • Silent RIG-2616 revert — the stack's generated code predated main's
    SessionError regen (45 -> 0 occurrences). The regen restores it: SessionError
    is back to 45 in go/gen/compass/v1/compass.pb.go and 14 in the agent TS,
    with ownerHandle and the transition arms additive on top.
  • Deleted approval-mode assertions (feat(agent): forge state-transition tools (RIG-3331) #1019) — restored the full approvalOf
    loop over all twelve tools (3 reads + 9 writes) with its justification comment,
    rather than the two-tool assertion that replaced it.

Mediums fixed: updated_at/created_at + updated_at_tables entry for
forge_state_transitions (main's RIG-3495 convention, which landed after this
branched) plus a sqlc regen; the single-column FK divergence documented; the
memo coordinate contract documented on rememberTransition; the memo-failure
error now names the forge write that landed; the Linear retry gate narrowed to
the actual staleness signal; workflow-state page truncation now fails loud at
422; the two transition schemas routed through the compassv1 barrel.

Both new provider tests were mutation-proved: widening the retry gate reddens
TestLinearTransitionDoesNotRetryOnNonStaleness200, and removing the truncation
guard reddens TestLinearTransitionRejectsTruncatedWorkflowStatePage.

Gate: moon ci 70 actions, 0 failed against MOON_BASE=origin/main.

The initial forge live-oracle 401s were mint contention, not a defect: the
Linear client_credentials app holds one active token, so five concurrent CI
runs each revoked the previous one's (which is why the last-to-mint PR was
green). Re-run serially, the job passes on every head with no code change.

@linear-code

linear-code Bot commented Sep 8, 2026

Copy link
Copy Markdown

RIG-3326

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-forge-rig-3326-owner.compass-eng-docs.pages.dev

Deployed from compass-forge/rig-3326-owner-wire at 7e23c7f.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant